﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.IO;

using eLibCommon;

namespace eLibClient
{
  public partial class frmClient : Form
  {
    private TcpClient _internalClient;
    private byte[] _readBuffer = new byte[256];
    private string _serverIP = "192.168.1.33";
    private int _port = 13000;

    private delegate void AppendTextDelegate(string myString);
    private AppendTextDelegate _statusAppender;

    public frmClient()
    {
      InitializeComponent();

      _statusAppender = new AppendTextDelegate(AppendStatusText);
      txtServerIP.Text = _serverIP;
      txtServerPort.Text = _port.ToString();
    }

    private void AppendStatusText(string text)
    {
      textBox1.AppendText(text);
    }
    
    private void btnConnect_Click(object sender, EventArgs e)
    {
      _serverIP = txtServerIP.Text;
      int.TryParse(txtServerPort.Text, out _port);

      this.CleanupClient();      
      _internalClient = new TcpClient();
      _internalClient.Connect(_serverIP, _port);

      this.WriteText("HELLO");
    }

    private void btnDisconnect_Click(object sender, EventArgs e)
    {
      this.WriteText("BYE");
    }

    private void CleanupClient()
    {
      if (_internalClient == null)
        return;

      if (_internalClient.Connected)
      {
        _internalClient.Client.Shutdown(SocketShutdown.Both);
        _internalClient.Client.Disconnect(false);
      }
      _internalClient.Client.Close();
      _internalClient.Close();
      _internalClient = null;
    }

    private void ReadText()
    {
      NetworkStream stream = _internalClient.GetStream();
      stream.BeginRead(_readBuffer
                     , 0
                     , _readBuffer.Length
                     , new AsyncCallback(this.OnReadComplete)
                     , null);
    }

    private void OnReadComplete(IAsyncResult ar)
    {
      if (_internalClient == null)
        return;

      if (!_internalClient.Connected)
        return;

      try
      {
        NetworkStream stream = _internalClient.GetStream();
        int bytesRead = stream.EndRead(ar);
        if (bytesRead > 0)
        {
          string receiveString = Encoding.ASCII.GetString(_readBuffer, 0, bytesRead);
          textBox1.Invoke(_statusAppender, new Object[] { receiveString });
          
          if (receiveString == "DISCONNECTED")
          {
            CleanupClient();
          }

          if (receiveString.Contains("NEWPORT"))
          {
            string[] parts = receiveString.Split(' ');
            int newPort = Convert.ToInt32(parts[1]);
            _internalClient = new TcpClient();
            _internalClient.Connect(_serverIP, newPort);
          }
        }

      }
      catch (IOException)
      {
      }
    }

    private void WriteText(string message)
    {
      if (_internalClient == null)
        return;

      NetworkStream stream = _internalClient.GetStream();
      StreamWriter writer = new StreamWriter(stream);
      writer.WriteLine(message);
      writer.Flush();

      this.ReadText();
    }

    private void btnLocalIP_Click(object sender, EventArgs e)
    {
      txtServerIP.Text = "127.0.0.1";
    }

    private void btnPing_Click(object sender, EventArgs e)
    {
      this.WriteText("PING");
    }

    private void frmClient_FormClosing(object sender, FormClosingEventArgs e)
    {
      this.WriteText("BYE");
    }



  }
}
